{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "4UAkYO8XUDxW"
      },
      "source": [
        "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/pinecone-io/examples/blob/master/learn/search/hybrid-search/ecommerce-search/ecommerce-search.ipynb) [![Open nbviewer](https://raw.githubusercontent.com/pinecone-io/examples/master/assets/nbviewer-shield.svg)](https://nbviewer.org/github/pinecone-io/examples/blob/master/learn/search/hybrid-search/ecommerce-search/ecommerce-search.ipynb)\n",
        "\n",
        "# Hybrid Search for E-Commerce with Pinecone"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "CrtPzpDfUN56"
      },
      "source": [
        "\n",
        "Hybrid vector search is combination of traditional keyword search and modern dense vector search. It has emerged as a powerful tool for e-commerce companies looking to improve the search experience for their customers.\n",
        "\n",
        "By combining the strengths of traditional text-based search algorithms with the visual recognition capabilities of deep learning models, hybrid vector search allows users to search for products using a combination of text and images. This can be especially useful for product searches, where customers may not know the exact name or details of the item they are looking for.\n",
        "\n",
        "Pinecone's new **sparse-dense index** allows you to seamlessly perform hybrid search for e-commerce or in any other context. This notebook demonstrates how to use the new hybrid search feature to improve e-commerce search."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Ug-NsCoZViN8"
      },
      "source": [
        "## Install Dependencies"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ZXObQEx82MIM"
      },
      "source": [
        "First, let's import the necessary libraries\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 52,
      "metadata": {
        "id": "NPPKJbKT_82b",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "73d5d5dc-2370-42c6-b190-1c1761cb33a3"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\u001b[?25l     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/1.0 MB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K     \u001b[91m━━━━━━━━━━\u001b[0m\u001b[90m╺\u001b[0m\u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.3/1.0 MB\u001b[0m \u001b[31m7.7 MB/s\u001b[0m eta \u001b[36m0:00:01\u001b[0m\r\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.0/1.0 MB\u001b[0m \u001b[31m15.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25h"
          ]
        }
      ],
      "source": [
        "!pip install -qU datasets transformers sentence-transformers \\\n",
        "                 pinecone-client pinecone-text protobuf==3.20.3"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Q68EZtCmooq4"
      },
      "source": [
        "## Connect to Pinecone"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "AwPHT3yIdn5y"
      },
      "source": [
        "Let's initiate a connection and create an index. For this, we need a [free API key](https://app.pinecone.io/), and then we initialize the connection like so:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 53,
      "metadata": {
        "id": "JluUgzTvrluL"
      },
      "outputs": [],
      "source": [
        "import os\n",
        "from pinecone import Pinecone\n",
        "\n",
        "# initialize connection to pinecone (get API key at app.pinecone.io)\n",
        "api_key = os.getenv(\"PINECONE_API_KEY\") or \"PINECONE_API_KEY\"\n",
        "# find your environment next to the api key in pinecone console\n",
        "env = os.getenv(\"PINECONE_ENVIRONMENT\") or \"PINECONE_ENVIRONMENT\"\n",
        "\n",
        "# init connection to pinecone\n",
        "pinecone.init(\n",
        "    api_key=api_key,\n",
        "    environment=env\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "7ZJ_n-hreMHD"
      },
      "source": [
        "To use the `sparse-dense` index in Pinecone we must set `metric=\"dotproduct\"` and use either `s1` or `p1` pods. We also align the `dimension` value to that of our retrieval model, which outputs `512`-dimensional vectors."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 54,
      "metadata": {
        "id": "I2KnKuHcuuk8"
      },
      "outputs": [],
      "source": [
        "# choose a name for your index\n",
        "index_name = \"hybrid-image-search\"\n",
        "\n",
        "if index_name not in pinecone.list_indexes().names():\n",
        "    # create the index\n",
        "    pinecone.create_index(\n",
        "      index_name,\n",
        "      dimension=512,\n",
        "      metric=\"dotproduct\",\n",
        "      pod_type=\"s1\"\n",
        "    )"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "PWdW7PGnsvcU"
      },
      "source": [
        "Now we have created the sparse-dense enabled index, we connect to it:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 55,
      "metadata": {
        "id": "Bi5Qik1vsvcU"
      },
      "outputs": [],
      "source": [
        "index = pinecone.Index(index_name)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "O6b5dTM8Cl1Y"
      },
      "source": [
        "*Note: we are using `Index` rather than `Index` for the improved upsert speeds, either can be used with the sparse-dense index.*"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "-ZjGAokB-L26"
      },
      "source": [
        "# Load Dataset"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ejDiNUhLp1iD"
      },
      "source": [
        "We will work with a subset of the [Open Fashion Product Images](https://www.kaggle.com/datasets/paramaggarwal/fashion-product-images-small) dataset, consisting of ~44K fashion products with images and category labels describing the products. The dataset can be loaded from the Huggigface Datasets hub as follows:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 56,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Y20qIflB-RWw",
        "outputId": "7f9356dd-f019-4435-ce02-f6d2d00d3772"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "WARNING:datasets.builder:Found cached dataset parquet (/root/.cache/huggingface/datasets/ashraq___parquet/ashraq--fashion-product-images-small-909c61a107795b31/0.0.0/2a3b91fbd88a2c90d1dbbb32b460cf621d31bd5b05b934492fdef7d8d6f236ec)\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "Dataset({\n",
              "    features: ['id', 'gender', 'masterCategory', 'subCategory', 'articleType', 'baseColour', 'season', 'year', 'usage', 'productDisplayName', 'image'],\n",
              "    num_rows: 44072\n",
              "})"
            ]
          },
          "metadata": {},
          "execution_count": 56
        }
      ],
      "source": [
        "from datasets import load_dataset\n",
        "\n",
        "# load the dataset from huggingface datasets hub\n",
        "fashion = load_dataset(\n",
        "    \"ashraq/fashion-product-images-small\",\n",
        "    split=\"train\"\n",
        ")\n",
        "fashion"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ceqgXtDCsezv"
      },
      "source": [
        "We will first assign the images and metadata into separate variables and then convert the metadata into a pandas dataframe."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 57,
      "metadata": {
        "id": "YUD_ZuZoCSLQ"
      },
      "outputs": [],
      "source": [
        "# assign the images and metadata to separate variables\n",
        "images = fashion[\"image\"]\n",
        "metadata = fashion.remove_columns(\"image\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 58,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 97
        },
        "id": "NnY4ivtzwcgO",
        "outputId": "5d38bdbe-10f5-49a7-9cc8-707c65092bf8"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80 at 0x7F78F6DF60D0>"
            ],
            "image/png": "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\n"
          },
          "metadata": {},
          "execution_count": 58
        }
      ],
      "source": [
        "# display a product image\n",
        "images[900]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 59,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 340
        },
        "id": "bedO24psC25h",
        "outputId": "6c234617-3577-4563-c2c3-aefbbcd0a314"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "      id gender masterCategory subCategory  articleType baseColour  season  \\\n",
              "0  15970    Men        Apparel     Topwear       Shirts  Navy Blue    Fall   \n",
              "1  39386    Men        Apparel  Bottomwear        Jeans       Blue  Summer   \n",
              "2  59263  Women    Accessories     Watches      Watches     Silver  Winter   \n",
              "3  21379    Men        Apparel  Bottomwear  Track Pants      Black    Fall   \n",
              "4  53759    Men        Apparel     Topwear      Tshirts       Grey  Summer   \n",
              "\n",
              "     year   usage                             productDisplayName  \n",
              "0  2011.0  Casual               Turtle Check Men Navy Blue Shirt  \n",
              "1  2012.0  Casual             Peter England Men Party Blue Jeans  \n",
              "2  2016.0  Casual                       Titan Women Silver Watch  \n",
              "3  2011.0  Casual  Manchester United Men Solid Black Track Pants  \n",
              "4  2012.0  Casual                          Puma Men Grey T-shirt  "
            ],
            "text/html": [
              "\n",
              "  <div id=\"df-5ef11971-78ad-4f00-a145-dd00a56a0b55\">\n",
              "    <div class=\"colab-df-container\">\n",
              "      <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>id</th>\n",
              "      <th>gender</th>\n",
              "      <th>masterCategory</th>\n",
              "      <th>subCategory</th>\n",
              "      <th>articleType</th>\n",
              "      <th>baseColour</th>\n",
              "      <th>season</th>\n",
              "      <th>year</th>\n",
              "      <th>usage</th>\n",
              "      <th>productDisplayName</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>15970</td>\n",
              "      <td>Men</td>\n",
              "      <td>Apparel</td>\n",
              "      <td>Topwear</td>\n",
              "      <td>Shirts</td>\n",
              "      <td>Navy Blue</td>\n",
              "      <td>Fall</td>\n",
              "      <td>2011.0</td>\n",
              "      <td>Casual</td>\n",
              "      <td>Turtle Check Men Navy Blue Shirt</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>39386</td>\n",
              "      <td>Men</td>\n",
              "      <td>Apparel</td>\n",
              "      <td>Bottomwear</td>\n",
              "      <td>Jeans</td>\n",
              "      <td>Blue</td>\n",
              "      <td>Summer</td>\n",
              "      <td>2012.0</td>\n",
              "      <td>Casual</td>\n",
              "      <td>Peter England Men Party Blue Jeans</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>59263</td>\n",
              "      <td>Women</td>\n",
              "      <td>Accessories</td>\n",
              "      <td>Watches</td>\n",
              "      <td>Watches</td>\n",
              "      <td>Silver</td>\n",
              "      <td>Winter</td>\n",
              "      <td>2016.0</td>\n",
              "      <td>Casual</td>\n",
              "      <td>Titan Women Silver Watch</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>21379</td>\n",
              "      <td>Men</td>\n",
              "      <td>Apparel</td>\n",
              "      <td>Bottomwear</td>\n",
              "      <td>Track Pants</td>\n",
              "      <td>Black</td>\n",
              "      <td>Fall</td>\n",
              "      <td>2011.0</td>\n",
              "      <td>Casual</td>\n",
              "      <td>Manchester United Men Solid Black Track Pants</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>53759</td>\n",
              "      <td>Men</td>\n",
              "      <td>Apparel</td>\n",
              "      <td>Topwear</td>\n",
              "      <td>Tshirts</td>\n",
              "      <td>Grey</td>\n",
              "      <td>Summer</td>\n",
              "      <td>2012.0</td>\n",
              "      <td>Casual</td>\n",
              "      <td>Puma Men Grey T-shirt</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "      <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-5ef11971-78ad-4f00-a145-dd00a56a0b55')\"\n",
              "              title=\"Convert this dataframe to an interactive table.\"\n",
              "              style=\"display:none;\">\n",
              "        \n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "       width=\"24px\">\n",
              "    <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
              "    <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
              "  </svg>\n",
              "      </button>\n",
              "      \n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      flex-wrap:wrap;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "      <script>\n",
              "        const buttonEl =\n",
              "          document.querySelector('#df-5ef11971-78ad-4f00-a145-dd00a56a0b55 button.colab-df-convert');\n",
              "        buttonEl.style.display =\n",
              "          google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "        async function convertToInteractive(key) {\n",
              "          const element = document.querySelector('#df-5ef11971-78ad-4f00-a145-dd00a56a0b55');\n",
              "          const dataTable =\n",
              "            await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                     [key], {});\n",
              "          if (!dataTable) return;\n",
              "\n",
              "          const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "            '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "            + ' to learn more about interactive tables.';\n",
              "          element.innerHTML = '';\n",
              "          dataTable['output_type'] = 'display_data';\n",
              "          await google.colab.output.renderOutput(dataTable, element);\n",
              "          const docLink = document.createElement('div');\n",
              "          docLink.innerHTML = docLinkHtml;\n",
              "          element.appendChild(docLink);\n",
              "        }\n",
              "      </script>\n",
              "    </div>\n",
              "  </div>\n",
              "  "
            ]
          },
          "metadata": {},
          "execution_count": 59
        }
      ],
      "source": [
        "# convert metadata into a pandas dataframe\n",
        "metadata = metadata.to_pandas()\n",
        "metadata.head()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "OWP2EAwMvDdA"
      },
      "source": [
        "We need both sparse and dense vectors to perform hybrid search. We will use all the metadata fields except for the `id` and `year` to create sparse vectors and the product images to create dense vectors."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "PyuqZHg_j22O"
      },
      "source": [
        "## Sparse Vectors"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "pj_-5m9p_f-9"
      },
      "source": [
        "To create the sparse vectors we'll use BM25. We import the BM25 function from the [`pinecone-text` library](https://github.com/pinecone-io/pinecone-text)."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 60,
      "metadata": {
        "id": "Zka805CX_f-9"
      },
      "outputs": [],
      "source": [
        "from pinecone_text.sparse import BM25Encoder\n",
        "\n",
        "bm25 = BM25Encoder()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "7UQEeCYgCl1Z"
      },
      "source": [
        "The tokenization will look something like this:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 61,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Woubfty5NBg9",
        "outputId": "676af06e-9201-4980-d224-dc07987f25fe"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "['turtle', 'check', 'men', 'navy', 'blue', 'shirt']"
            ]
          },
          "metadata": {},
          "execution_count": 61
        }
      ],
      "source": [
        "\"Turtle Check Men Navy Blue Shirt\".lower().split()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "zPbCsMeHKGbQ"
      },
      "source": [
        "BM25 requires training on a representative portion of the dataset. We do this like so:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 62,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 66,
          "referenced_widgets": [
            "d7053209fd6644f682d4a5e96d18d373",
            "f16d4512a1d34da8a2fa2c09d50e41aa",
            "bdf132316bab418fb7399f7808efec31",
            "d3ae406fd35a4f1087e8cca629457600",
            "09b685660d21477d8cc5cc7937c6e0b6",
            "d4a4038751c042bdb369bc77f8633ccc",
            "3c020c04e591416e8ad21af942219914",
            "e65864147f4d41f8894df36f4325261f",
            "dcdac64951e64ccfb75443d2da5f2696",
            "1238d2cfb76f488a8d71185561b21fd1",
            "b3735eec29344b5fb16005b22a150c78"
          ]
        },
        "id": "DJ0uOvEkKGze",
        "outputId": "f038fc5a-778a-4d63-d64f-b2f3a142f7f4"
      },
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "  0%|          | 0/44072 [00:00<?, ?it/s]"
            ],
            "application/vnd.jupyter.widget-view+json": {
              "version_major": 2,
              "version_minor": 0,
              "model_id": "d7053209fd6644f682d4a5e96d18d373"
            }
          },
          "metadata": {}
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<pinecone_text.sparse.bm25_encoder.BM25Encoder at 0x7f78f7851220>"
            ]
          },
          "metadata": {},
          "execution_count": 62
        }
      ],
      "source": [
        "bm25.fit(metadata['productDisplayName'])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "rwCSrQR4kYOT"
      },
      "source": [
        "Let's create a test sparse vector using a `productDisplayName`."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 63,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 35
        },
        "id": "fm9PSUD1Lqum",
        "outputId": "7a570355-2b4b-4c86-a7de-9d123776d665"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "'Turtle Check Men Navy Blue Shirt'"
            ],
            "application/vnd.google.colaboratory.intrinsic+json": {
              "type": "string"
            }
          },
          "metadata": {},
          "execution_count": 63
        }
      ],
      "source": [
        "metadata['productDisplayName'][0]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 64,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "lyOLD6NeLgiC",
        "outputId": "b3fe2562-2b7e-43bc-ddb4-c338836b9774"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "{'indices': [23789636,\n",
              "  1830646559,\n",
              "  632192512,\n",
              "  931643408,\n",
              "  3905155331,\n",
              "  3828986392],\n",
              " 'values': [0.3276687848622804,\n",
              "  0.19377339510596148,\n",
              "  0.040475545164610806,\n",
              "  0.1808640794607714,\n",
              "  0.10791423980552016,\n",
              "  0.1493039556008558]}"
            ]
          },
          "metadata": {},
          "execution_count": 64
        }
      ],
      "source": [
        "bm25.encode_queries(metadata['productDisplayName'][0])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "417gwcNNkm55"
      },
      "source": [
        "And for the stored docs, we only need the \"IDF\" part:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 65,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "nvhEqFTikrH2",
        "outputId": "a0562f66-3b08-4cce-91bb-9cc8df36464b"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "{'indices': [23789636,\n",
              "  1830646559,\n",
              "  632192512,\n",
              "  931643408,\n",
              "  3905155331,\n",
              "  3828986392],\n",
              " 'values': [0.4449638258432887,\n",
              "  0.4449638258432887,\n",
              "  0.4449638258432887,\n",
              "  0.4449638258432887,\n",
              "  0.4449638258432887,\n",
              "  0.4449638258432887]}"
            ]
          },
          "metadata": {},
          "execution_count": 65
        }
      ],
      "source": [
        "bm25.encode_documents(metadata['productDisplayName'][0])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3EXN_DWknlKT"
      },
      "source": [
        "## Dense Vectors"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "YA4muHaL_f--"
      },
      "source": [
        "We will use the CLIP to generate dense vectors for product images. We can directly pass PIL images to CLIP as it can encode both images and texts. We can load CLIP like so:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 66,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "7_DTvjGw_f-_",
        "outputId": "629b53d5-603f-4d7c-913b-730fb8ab055e"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "SentenceTransformer(\n",
              "  (0): CLIPModel()\n",
              ")"
            ]
          },
          "metadata": {},
          "execution_count": 66
        }
      ],
      "source": [
        "from sentence_transformers import SentenceTransformer\n",
        "import torch\n",
        "\n",
        "device = 'cuda' if torch.cuda.is_available() else 'cpu'\n",
        "\n",
        "# load a CLIP model from huggingface\n",
        "model = SentenceTransformer(\n",
        "    'sentence-transformers/clip-ViT-B-32',\n",
        "    device=device\n",
        ")\n",
        "model"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 67,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "lkK_ipwHeNCj",
        "outputId": "3e00c794-c6e5-4ee0-c86d-d9dbc764a913"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(1, 512)"
            ]
          },
          "metadata": {},
          "execution_count": 67
        }
      ],
      "source": [
        "dense_vec = model.encode([metadata['productDisplayName'][0]])\n",
        "dense_vec.shape"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "mkdXK8b4_f-_"
      },
      "source": [
        "The model gives us a `512` dimensional dense vector."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "wph64ujXrhrp"
      },
      "source": [
        "## Upsert Documents"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "oX99CnOroEq0"
      },
      "source": [
        "Now we can go ahead and generate sparse and dense vectors for the full dataset and upsert them along with the metadata to the new hybrid index. We can do that easily as follows:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 69,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 118,
          "referenced_widgets": [
            "0acdc92e9da747a69525d163805eff25",
            "2b2bca75df6d4d2887f56f2a5a523a0d",
            "e174c6ce8fe3413bbb91b51825969942",
            "23e1a1373c1c483a9e02550d3bb523c0",
            "5ba9d33f1ab44a628e44f4fdac243b3e",
            "f6aa6a057b344807b50da7fd3726e1a2",
            "89b0b8f1adc24bb28ed796bf6219d77e",
            "f103af701fa04abba0032f9a2e7ee0a0",
            "58ad5636f6404c6ba008a0a0a2df0203",
            "dfe54e9c17ad47e287b5583a396a260d",
            "1b840c7e106143379e13e422cb35b1eb"
          ]
        },
        "id": "vcM5h0T1_f-_",
        "outputId": "7eac5d5f-44a8-4ac0-d3e7-b229ffbdc8be"
      },
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "  0%|          | 0/221 [00:00<?, ?it/s]"
            ],
            "application/vnd.jupyter.widget-view+json": {
              "version_major": 2,
              "version_minor": 0,
              "model_id": "0acdc92e9da747a69525d163805eff25"
            }
          },
          "metadata": {}
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "{'dimension': 512,\n",
              " 'index_fullness': 0.0,\n",
              " 'namespaces': {'': {'vector_count': 44072}},\n",
              " 'total_vector_count': 44072}"
            ]
          },
          "metadata": {},
          "execution_count": 69
        }
      ],
      "source": [
        "from tqdm.auto import tqdm\n",
        "\n",
        "batch_size = 200\n",
        "\n",
        "for i in tqdm(range(0, len(fashion), batch_size)):\n",
        "    # find end of batch\n",
        "    i_end = min(i+batch_size, len(fashion))\n",
        "    # extract metadata batch\n",
        "    meta_batch = metadata.iloc[i:i_end]\n",
        "    meta_dict = meta_batch.to_dict(orient=\"records\")\n",
        "    # concatinate all metadata field except for id and year to form a single string\n",
        "    meta_batch = [\" \".join(x) for x in meta_batch.loc[:, ~meta_batch.columns.isin(['id', 'year'])].values.tolist()]\n",
        "    # extract image batch\n",
        "    img_batch = images[i:i_end]\n",
        "    # create sparse BM25 vectors\n",
        "    sparse_embeds = bm25.encode_documents([text for text in meta_batch])\n",
        "    # create dense vectors\n",
        "    dense_embeds = model.encode(img_batch).tolist()\n",
        "    # create unique IDs\n",
        "    ids = [str(x) for x in range(i, i_end)]\n",
        "\n",
        "    upserts = []\n",
        "    # loop through the data and create dictionaries for uploading documents to pinecone index\n",
        "    for _id, sparse, dense, meta in zip(ids, sparse_embeds, dense_embeds, meta_dict):\n",
        "        upserts.append({\n",
        "            'id': _id,\n",
        "            'sparse_values': sparse,\n",
        "            'values': dense,\n",
        "            'metadata': meta\n",
        "        })\n",
        "    # upload the documents to the new hybrid index\n",
        "    index.upsert(upserts)\n",
        "\n",
        "# show index description after uploading the documents\n",
        "index.describe_index_stats()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ir1n8ABfqbV-"
      },
      "source": [
        "## Querying"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "vv24_cjVrVKz"
      },
      "source": [
        "Now we can query the index, providing the sparse and dense vectors. We do this directly with an equal weighting between sparse and dense like so:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 70,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "vZRRVafUnp2j",
        "outputId": "1b0e14ba-4ab9-4f76-b365-923f448bdac2"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80 at 0x7F7815E08490>,\n",
              " <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80 at 0x7F7814DB9FD0>,\n",
              " <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80 at 0x7F7809BEC550>,\n",
              " <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80 at 0x7F78076469A0>,\n",
              " <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80 at 0x7F78067FDFD0>,\n",
              " <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80 at 0x7F7814FA0B50>,\n",
              " <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80 at 0x7F78073EB370>,\n",
              " <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80 at 0x7F7809CBC790>,\n",
              " <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80 at 0x7F783084E730>,\n",
              " <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80 at 0x7F7816291730>,\n",
              " <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80 at 0x7F7809EC81C0>,\n",
              " <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80 at 0x7F78158CFEE0>,\n",
              " <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80 at 0x7F78160979A0>,\n",
              " <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80 at 0x7F7807C7C8B0>]"
            ]
          },
          "metadata": {},
          "execution_count": 70
        }
      ],
      "source": [
        "query = \"dark blue french connection jeans for men\"\n",
        "\n",
        "# create sparse and dense vectors\n",
        "sparse = bm25.encode_queries(query)\n",
        "dense = model.encode(query).tolist()\n",
        "# search\n",
        "result = index.query(\n",
        "    top_k=14,\n",
        "    vector=dense,\n",
        "    sparse_vector=sparse,\n",
        "    include_metadata=True\n",
        ")\n",
        "# used returned product ids to get images\n",
        "imgs = [images[int(r[\"id\"])] for r in result[\"matches\"]]\n",
        "imgs"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "72smh7wAsNid"
      },
      "source": [
        "We return a list of PIL image objects, to view them we will define a function called `display_result`."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 71,
      "metadata": {
        "id": "6OYu8PwItPXe"
      },
      "outputs": [],
      "source": [
        "from IPython.core.display import HTML\n",
        "from io import BytesIO\n",
        "from base64 import b64encode\n",
        "\n",
        "# function to display product images\n",
        "def display_result(image_batch):\n",
        "    figures = []\n",
        "    for img in image_batch:\n",
        "        b = BytesIO()  \n",
        "        img.save(b, format='png')\n",
        "        figures.append(f'''\n",
        "            <figure style=\"margin: 5px !important;\">\n",
        "              <img src=\"data:image/png;base64,{b64encode(b.getvalue()).decode('utf-8')}\" style=\"width: 90px; height: 120px\" >\n",
        "            </figure>\n",
        "        ''')\n",
        "    return HTML(data=f'''\n",
        "        <div style=\"display: flex; flex-flow: row wrap; text-align: center;\">\n",
        "        {''.join(figures)}\n",
        "        </div>\n",
        "    ''')"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "PQAn1-jNsWmA"
      },
      "source": [
        "And now we can view them:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 72,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 286
        },
        "id": "PRfILXeBsYgQ",
        "outputId": "12f6c89c-dc25-41db-c2f0-923211f8510f"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ],
            "text/html": [
              "\n",
              "        <div style=\"display: flex; flex-flow: row wrap; text-align: center;\">\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "        </div>\n",
              "    "
            ]
          },
          "metadata": {},
          "execution_count": 72
        }
      ],
      "source": [
        "display_result(imgs)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "2SMzxAsXsyOj"
      },
      "source": [
        "It's possible to prioritize our search based on sparse vs. dense vector results. To do so, we scale the vectors, for this we'll use a function named `hybrid_scale`."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 73,
      "metadata": {
        "id": "50bjbcmIvAuP"
      },
      "outputs": [],
      "source": [
        "def hybrid_scale(dense, sparse, alpha: float):\n",
        "    \"\"\"Hybrid vector scaling using a convex combination\n",
        "\n",
        "    alpha * dense + (1 - alpha) * sparse\n",
        "\n",
        "    Args:\n",
        "        dense: Array of floats representing\n",
        "        sparse: a dict of `indices` and `values`\n",
        "        alpha: float between 0 and 1 where 0 == sparse only\n",
        "               and 1 == dense only\n",
        "    \"\"\"\n",
        "    if alpha < 0 or alpha > 1:\n",
        "        raise ValueError(\"Alpha must be between 0 and 1\")\n",
        "    # scale sparse and dense vectors to create hybrid search vecs\n",
        "    hsparse = {\n",
        "        'indices': sparse['indices'],\n",
        "        'values':  [v * (1 - alpha) for v in sparse['values']]\n",
        "    }\n",
        "    hdense = [v * alpha for v in dense]\n",
        "    return hdense, hsparse"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "TBjad1-cvRlA"
      },
      "source": [
        "First, we will do a pure sparse vector search by setting the alpha value as 0."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 74,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 286
        },
        "id": "f6dHXhrms6ao",
        "outputId": "769da0b1-0697-4f5a-ee38-de579ac5ec5f"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ],
            "text/html": [
              "\n",
              "        <div style=\"display: flex; flex-flow: row wrap; text-align: center;\">\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "        </div>\n",
              "    "
            ]
          },
          "metadata": {},
          "execution_count": 74
        }
      ],
      "source": [
        "question = \"dark blue french connection jeans for men\"\n",
        "\n",
        "# scale sparse and dense vectors\n",
        "hdense, hsparse = hybrid_scale(dense, sparse, alpha=0)\n",
        "# search\n",
        "result = index.query(\n",
        "    top_k=14,\n",
        "    vector=hdense,\n",
        "    sparse_vector=hsparse,\n",
        "    include_metadata=True\n",
        ")\n",
        "# used returned product ids to get images\n",
        "imgs = [images[int(r[\"id\"])] for r in result[\"matches\"]]\n",
        "# display the images\n",
        "display_result(imgs)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "b_qFgTJNYQmG"
      },
      "source": [
        "Let's take a look at the description of the result."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 75,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "uMtT5myIYMOq",
        "outputId": "8ce979f9-5f57-46ba-c02a-b81e1db639b6"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "French Connection Men Blue Jeans\n",
            "French Connection Men Blue Jeans\n",
            "French Connection Men Blue Jeans\n",
            "French Connection Men Blue Jeans\n",
            "French Connection Men Blue Jeans\n",
            "French Connection Men Blue Jeans\n",
            "French Connection Women Blue Jeans\n",
            "French Connection Women Blue Jeans\n",
            "French Connection Men Navy Blue Jeans\n",
            "French Connection Men Blue paint Stained Regular Fit Jeans\n",
            "French Connection Men Black Jeans\n",
            "French Connection Men Black Jeans\n",
            "French Connection Men Black Jeans\n",
            "French Connection Men Black Jeans\n"
          ]
        }
      ],
      "source": [
        "for x in result[\"matches\"]:\n",
        "    print(x[\"metadata\"]['productDisplayName'])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Qy19HdKfYYwf"
      },
      "source": [
        "We can observe that the keyword search returned French Connection jeans but failed to rank the men's French Connection jeans higher than a few of the women's. Now let's do a pure semantic image search by setting the alpha value to 1."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 76,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 286
        },
        "id": "kQ6IV7fcFah7",
        "outputId": "feabd996-438c-4cce-886b-591c7b4d7807"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ],
            "text/html": [
              "\n",
              "        <div style=\"display: flex; flex-flow: row wrap; text-align: center;\">\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "        </div>\n",
              "    "
            ]
          },
          "metadata": {},
          "execution_count": 76
        }
      ],
      "source": [
        "# scale sparse and dense vectors\n",
        "hdense, hsparse = hybrid_scale(dense, sparse, alpha=1)\n",
        "# search\n",
        "result = index.query(\n",
        "    top_k=14,\n",
        "    vector=hdense,\n",
        "    sparse_vector=hsparse,\n",
        "    include_metadata=True\n",
        ")\n",
        "# used returned product ids to get images\n",
        "imgs = [images[int(r[\"id\"])] for r in result[\"matches\"]]\n",
        "# display the images\n",
        "display_result(imgs)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 77,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "7AG7BjKZaGQ9",
        "outputId": "256a5ce5-a7a4-4450-e133-aac2799f6aee"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Locomotive Men Radley Blue Jeans\n",
            "Locomotive Men Race Blue Jeans\n",
            "Locomotive Men Eero Blue Jeans\n",
            "Locomotive Men Cam Blue Jeans\n",
            "Locomotive Men Ian Blue Jeans\n",
            "French Connection Men Blue Jeans\n",
            "Locomotive Men Cael Blue Jeans\n",
            "Locomotive Men Lio Blue Jeans\n",
            "French Connection Men Blue Jeans\n",
            "Locomotive Men Rafe Blue Jeans\n",
            "Locomotive Men Barney Grey Jeans\n",
            "Spykar Men Actif Fit Low Waist Blue Jeans\n",
            "Spykar Men Style Essentials Kns 0542 Blue Jeans\n",
            "Wrangler Men Blue Skanders Jeans\n"
          ]
        }
      ],
      "source": [
        "for x in result[\"matches\"]:\n",
        "    print(x[\"metadata\"]['productDisplayName'])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "vJ-qOWLbaRGc"
      },
      "source": [
        "The semantic image search correctly returned blue jeans for men, but mostly failed to match the exact brand we are looking for — French Connection. Now let's set the alpha value to `0.05` to try a hybrid search that is slightly more dense than sparse search."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 78,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 286
        },
        "id": "gif9gPPYbcLX",
        "outputId": "20d8cb40-813e-40d0-b9f6-4e29835d3739"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ],
            "text/html": [
              "\n",
              "        <div style=\"display: flex; flex-flow: row wrap; text-align: center;\">\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "        </div>\n",
              "    "
            ]
          },
          "metadata": {},
          "execution_count": 78
        }
      ],
      "source": [
        "# scale sparse and dense vectors\n",
        "hdense, hsparse = hybrid_scale(dense, sparse, alpha=0.05)\n",
        "# search\n",
        "result = index.query(\n",
        "    top_k=14,\n",
        "    vector=hdense,\n",
        "    sparse_vector=hsparse,\n",
        "    include_metadata=True\n",
        ")\n",
        "# used returned product ids to get images\n",
        "imgs = [images[int(r[\"id\"])] for r in result[\"matches\"]]\n",
        "# display the images\n",
        "display_result(imgs)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 79,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "CjusvHJ5b7IQ",
        "outputId": "2f5c897b-5a1e-427f-eb4e-4ffd5a441992"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "French Connection Men Blue Jeans\n",
            "French Connection Men Blue Jeans\n",
            "French Connection Men Blue Jeans\n",
            "Locomotive Men Radley Blue Jeans\n",
            "French Connection Men Navy Blue Jeans\n",
            "Locomotive Men Race Blue Jeans\n",
            "Locomotive Men Eero Blue Jeans\n",
            "Locomotive Men Cam Blue Jeans\n",
            "French Connection Men Blue Jeans\n",
            "French Connection Men Blue paint Stained Regular Fit Jeans\n",
            "Locomotive Men Ian Blue Jeans\n",
            "Locomotive Men Cael Blue Jeans\n",
            "French Connection Men Blue Jeans\n",
            "Locomotive Men Lio Blue Jeans\n"
          ]
        }
      ],
      "source": [
        "for x in result[\"matches\"]:\n",
        "    print(x[\"metadata\"]['productDisplayName'])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "rADVMg4Jymn-"
      },
      "source": [
        "By performing a mostly sparse search with some help from our image-based dense vectors, we get a strong number of French Connection jeans, that are for men, and visually are almost all aligned to blue jeans."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "N7NmPqeihyCs"
      },
      "source": [
        "Let's try more queries."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 81,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 286
        },
        "id": "vxxITNeYb7Lv",
        "outputId": "2b91fbc1-4bf6-4663-c68a-12af6784858e"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ],
            "text/html": [
              "\n",
              "        <div style=\"display: flex; flex-flow: row wrap; text-align: center;\">\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "        </div>\n",
              "    "
            ]
          },
          "metadata": {},
          "execution_count": 81
        }
      ],
      "source": [
        "query = \"small beige handbag for women\"\n",
        "# create sparse and dense vectors\n",
        "sparse = bm25.encode_queries(query)\n",
        "dense = model.encode(query).tolist()\n",
        "# scale sparse and dense vectors - keyword search first\n",
        "hdense, hsparse = hybrid_scale(dense, sparse, alpha=0)\n",
        "# search\n",
        "result = index.query(\n",
        "    top_k=14,\n",
        "    vector=hdense,\n",
        "    sparse_vector=hsparse,\n",
        "    include_metadata=True\n",
        ")\n",
        "# used returned product ids to get images\n",
        "imgs = [images[int(r[\"id\"])] for r in result[\"matches\"]]\n",
        "# display the images\n",
        "display_result(imgs)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "SH9Q-9FrzcQj"
      },
      "source": [
        "We get a lot of small handbags for women, but they're not beige. Let's use the image dense vectors to weigh the colors higher."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 82,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 286
        },
        "id": "H8P7okTXmoHf",
        "outputId": "69fc7cd0-829b-42d4-c1fb-612dde2a749d"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ],
            "text/html": [
              "\n",
              "        <div style=\"display: flex; flex-flow: row wrap; text-align: center;\">\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "        </div>\n",
              "    "
            ]
          },
          "metadata": {},
          "execution_count": 82
        }
      ],
      "source": [
        "# scale sparse and dense vectors\n",
        "hdense, hsparse = hybrid_scale(dense, sparse, alpha=0.05)\n",
        "# search\n",
        "result = index.query(\n",
        "    top_k=14,\n",
        "    vector=hdense,\n",
        "    sparse_vector=hsparse,\n",
        "    include_metadata=True\n",
        ")\n",
        "# used returned product ids to get images\n",
        "imgs = [images[int(r[\"id\"])] for r in result[\"matches\"]]\n",
        "# display the images\n",
        "display_result(imgs)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 83,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "qgCaaMdJ0CfC",
        "outputId": "2fa86acd-8c3b-4861-d2b4-d5c6acb9d8c9"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Rocky S Women Beige Handbag\n",
            "Kiara Women Beige Handbag\n",
            "Baggit Women Beige Handbag\n",
            "Lino Perros Women Beige Handbag\n",
            "Kiara Women Beige Handbag\n",
            "Kiara Women Beige Handbag\n",
            "Murcia Women Beige Handbag\n",
            "Rocia Women Beige Handbag\n",
            "Murcia Women Hahk Beige Handbags\n",
            "French Connection Women Beige Handbag\n",
            "Baggit Women Beige Handbag\n",
            "Murcia Women Emma Beige Handbags\n",
            "Murcia Women Emma Beige Handbags\n",
            "Murcia Women Hddcs Beige Handbags\n"
          ]
        }
      ],
      "source": [
        "for x in result[\"matches\"]:\n",
        "    print(x[\"metadata\"]['productDisplayName'])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "u0qtocM9n09a"
      },
      "source": [
        "Here we see better aligned handbags."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 84,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 286
        },
        "id": "CnrYxBvUzya6",
        "outputId": "56b76d28-2142-4077-c815-0d8ca07874ef"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ],
            "text/html": [
              "\n",
              "        <div style=\"display: flex; flex-flow: row wrap; text-align: center;\">\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "        </div>\n",
              "    "
            ]
          },
          "metadata": {},
          "execution_count": 84
        }
      ],
      "source": [
        "# scale sparse and dense vectors\n",
        "hdense, hsparse = hybrid_scale(dense, sparse, alpha=1)\n",
        "# search\n",
        "result = index.query(\n",
        "    top_k=14,\n",
        "    vector=hdense,\n",
        "    sparse_vector=hsparse,\n",
        "    include_metadata=True\n",
        ")\n",
        "# used returned product ids to get images\n",
        "imgs = [images[int(r[\"id\"])] for r in result[\"matches\"]]\n",
        "# display the images\n",
        "display_result(imgs)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "z54twxIs0NiA"
      },
      "source": [
        "If we go too far with dense vectors, we start to see a few purses, rather than handbags."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "BFYd1Grqozjv"
      },
      "source": [
        "Let's run some more interesting queries. This time we will use a **product image** to create our dense vector, we'll provide a text query as before that will be used to create the sparse vector, and then we'll select a specific color as per the metadata attached to each image, with [metadata filtering](https://docs.pinecone.io/docs/metadata-filtering)."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 86,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 97
        },
        "id": "SbP92tB_wIoO",
        "outputId": "e0a6219f-3a87-47e9-b6ad-91652a06a470"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80 at 0x7F7807F8A3A0>"
            ],
            "image/png": "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\n"
          },
          "metadata": {},
          "execution_count": 86
        }
      ],
      "source": [
        "images[36254]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 85,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 286
        },
        "id": "HZWMLcwxwMLi",
        "outputId": "152b74ae-1a14-4a8f-ff75-1f93b108ac0e"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ],
            "text/html": [
              "\n",
              "        <div style=\"display: flex; flex-flow: row wrap; text-align: center;\">\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "        </div>\n",
              "    "
            ]
          },
          "metadata": {},
          "execution_count": 85
        }
      ],
      "source": [
        "query = \"soft purple topwear\"\n",
        "# create the sparse vector\n",
        "sparse = bm25.encode_queries(query)\n",
        "# now create the dense vector using the image\n",
        "dense = model.encode(images[36254]).tolist()\n",
        "# scale sparse and dense vectors\n",
        "hdense, hsparse = hybrid_scale(dense, sparse, alpha=0.3)\n",
        "# search\n",
        "result = index.query(\n",
        "    top_k=14,\n",
        "    vector=hdense,\n",
        "    sparse_vector=hsparse,\n",
        "    include_metadata=True\n",
        ")\n",
        "# use returned product ids to get images\n",
        "imgs = [images[int(r[\"id\"])] for r in result[\"matches\"]]\n",
        "# display the images\n",
        "display_result(imgs)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "do5q3HYg1-Nl"
      },
      "source": [
        "Our \"purple\" component isn't being considered strongly enough, let's add this to the metadata filtering:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 88,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 286
        },
        "id": "ItQ7OORc2AN0",
        "outputId": "a49d9c30-cd61-4870-f5f1-9cee6b5888f5"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ],
            "text/html": [
              "\n",
              "        <div style=\"display: flex; flex-flow: row wrap; text-align: center;\">\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "        </div>\n",
              "    "
            ]
          },
          "metadata": {},
          "execution_count": 88
        }
      ],
      "source": [
        "query = \"soft purple topwear\"\n",
        "# create the sparse vector\n",
        "sparse = bm25.encode_queries(query)\n",
        "# now create the dense vector using the image\n",
        "dense = model.encode(images[36254]).tolist()\n",
        "# scale sparse and dense vectors\n",
        "hdense, hsparse = hybrid_scale(dense, sparse, alpha=0.3)\n",
        "# search\n",
        "result = index.query(\n",
        "    top_k=14,\n",
        "    vector=hdense,\n",
        "    sparse_vector=hsparse,\n",
        "    include_metadata=True,\n",
        "    filter={\"baseColour\": \"Purple\"}  # add to metadata filter\n",
        ")\n",
        "# used returned product ids to get images\n",
        "imgs = [images[int(r[\"id\"])] for r in result[\"matches\"]]\n",
        "# display the images\n",
        "display_result(imgs)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "FKNDcL0f2gx9"
      },
      "source": [
        "Let's try with another image:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 90,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 97
        },
        "id": "tI5EL2MdwMM9",
        "outputId": "9aa9f78e-3cac-47d2-e91f-511afe5a9d6e"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80 at 0x7F7807F8A670>"
            ],
            "image/png": "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\n"
          },
          "metadata": {},
          "execution_count": 90
        }
      ],
      "source": [
        "images[36256]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 89,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 286
        },
        "id": "0WEpUy3Asuxs",
        "outputId": "392e334f-a76a-445b-8cf4-659c56287c4a"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ],
            "text/html": [
              "\n",
              "        <div style=\"display: flex; flex-flow: row wrap; text-align: center;\">\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "            <figure style=\"margin: 5px !important;\">\n",
              "              <img src=\"\" style=\"width: 90px; height: 120px\" >\n",
              "            </figure>\n",
              "        \n",
              "        </div>\n",
              "    "
            ]
          },
          "metadata": {},
          "execution_count": 89
        }
      ],
      "source": [
        "query = \"soft green color topwear\"\n",
        "# create the sparse vector\n",
        "sparse = bm25.encode_queries(query)\n",
        "# now create the dense vector using the image\n",
        "dense = model.encode(images[36256]).tolist()\n",
        "# scale sparse and dense vectors\n",
        "hdense, hsparse = hybrid_scale(dense, sparse, alpha=0.6)\n",
        "# search\n",
        "result = index.query(\n",
        "    top_k=14,\n",
        "    vector=hdense,\n",
        "    sparse_vector=hsparse,\n",
        "    include_metadata=True,\n",
        "    filter={\"baseColour\": \"Green\"}  # add to metadata filter\n",
        ")\n",
        "# use returned product ids to get images\n",
        "imgs = [images[int(r[\"id\"])] for r in result[\"matches\"]]\n",
        "# display the images\n",
        "display_result(imgs)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "SY5hZZlR0Zrs"
      },
      "source": [
        "Here we did not specify the gender but the search results are accurate and we got products matching our query image and description."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "1YY3hiL3xNQ5"
      },
      "source": [
        "# Delete the Index\n",
        "\n",
        "If you're done with the index, we delete it to save resources."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 91,
      "metadata": {
        "id": "DnGtG5iaUArB"
      },
      "outputs": [],
      "source": [
        "pinecone.delete_index(index_name)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "jMHsCU3FKdC2"
      },
      "source": [
        "---"
      ]
    }
  ],
  "metadata": {
    "accelerator": "GPU",
    "colab": {
      "provenance": []
    },
    "environment": {
      "kernel": "python3",
      "name": "common-cu110.m95",
      "type": "gcloud",
      "uri": "gcr.io/deeplearning-platform-release/base-cu110:m95"
    },
    "gpuClass": "standard",
    "kernelspec": {
      "display_name": "ml",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.9.12"
    },
    "vscode": {
      "interpreter": {
        "hash": "b8e7999f96e1b425e2d542f21b571f5a4be3e97158b0b46ea1b2500df63956ce"
      }
    },
    "widgets": {
      "application/vnd.jupyter.widget-state+json": {
        "d7053209fd6644f682d4a5e96d18d373": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HBoxModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HBoxModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HBoxView",
            "box_style": "",
            "children": [
              "IPY_MODEL_f16d4512a1d34da8a2fa2c09d50e41aa",
              "IPY_MODEL_bdf132316bab418fb7399f7808efec31",
              "IPY_MODEL_d3ae406fd35a4f1087e8cca629457600"
            ],
            "layout": "IPY_MODEL_09b685660d21477d8cc5cc7937c6e0b6"
          }
        },
        "f16d4512a1d34da8a2fa2c09d50e41aa": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HTMLModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_d4a4038751c042bdb369bc77f8633ccc",
            "placeholder": "​",
            "style": "IPY_MODEL_3c020c04e591416e8ad21af942219914",
            "value": "100%"
          }
        },
        "bdf132316bab418fb7399f7808efec31": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "FloatProgressModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "FloatProgressModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "ProgressView",
            "bar_style": "success",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_e65864147f4d41f8894df36f4325261f",
            "max": 44072,
            "min": 0,
            "orientation": "horizontal",
            "style": "IPY_MODEL_dcdac64951e64ccfb75443d2da5f2696",
            "value": 44072
          }
        },
        "d3ae406fd35a4f1087e8cca629457600": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HTMLModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_1238d2cfb76f488a8d71185561b21fd1",
            "placeholder": "​",
            "style": "IPY_MODEL_b3735eec29344b5fb16005b22a150c78",
            "value": " 44072/44072 [00:07&lt;00:00, 5889.22it/s]"
          }
        },
        "09b685660d21477d8cc5cc7937c6e0b6": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "d4a4038751c042bdb369bc77f8633ccc": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "3c020c04e591416e8ad21af942219914": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "DescriptionStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        },
        "e65864147f4d41f8894df36f4325261f": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "dcdac64951e64ccfb75443d2da5f2696": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "ProgressStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "ProgressStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "bar_color": null,
            "description_width": ""
          }
        },
        "1238d2cfb76f488a8d71185561b21fd1": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "b3735eec29344b5fb16005b22a150c78": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "DescriptionStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        },
        "0acdc92e9da747a69525d163805eff25": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HBoxModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HBoxModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HBoxView",
            "box_style": "",
            "children": [
              "IPY_MODEL_2b2bca75df6d4d2887f56f2a5a523a0d",
              "IPY_MODEL_e174c6ce8fe3413bbb91b51825969942",
              "IPY_MODEL_23e1a1373c1c483a9e02550d3bb523c0"
            ],
            "layout": "IPY_MODEL_5ba9d33f1ab44a628e44f4fdac243b3e"
          }
        },
        "2b2bca75df6d4d2887f56f2a5a523a0d": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HTMLModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_f6aa6a057b344807b50da7fd3726e1a2",
            "placeholder": "​",
            "style": "IPY_MODEL_89b0b8f1adc24bb28ed796bf6219d77e",
            "value": "100%"
          }
        },
        "e174c6ce8fe3413bbb91b51825969942": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "FloatProgressModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "FloatProgressModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "ProgressView",
            "bar_style": "success",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_f103af701fa04abba0032f9a2e7ee0a0",
            "max": 221,
            "min": 0,
            "orientation": "horizontal",
            "style": "IPY_MODEL_58ad5636f6404c6ba008a0a0a2df0203",
            "value": 221
          }
        },
        "23e1a1373c1c483a9e02550d3bb523c0": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HTMLModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_dfe54e9c17ad47e287b5583a396a260d",
            "placeholder": "​",
            "style": "IPY_MODEL_1b840c7e106143379e13e422cb35b1eb",
            "value": " 221/221 [08:17&lt;00:00,  1.79s/it]"
          }
        },
        "5ba9d33f1ab44a628e44f4fdac243b3e": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "f6aa6a057b344807b50da7fd3726e1a2": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "89b0b8f1adc24bb28ed796bf6219d77e": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "DescriptionStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        },
        "f103af701fa04abba0032f9a2e7ee0a0": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "58ad5636f6404c6ba008a0a0a2df0203": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "ProgressStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "ProgressStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "bar_color": null,
            "description_width": ""
          }
        },
        "dfe54e9c17ad47e287b5583a396a260d": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "1b840c7e106143379e13e422cb35b1eb": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "DescriptionStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        }
      }
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}